/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import React, { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useState } from 'react';
import { AdaptiveSideSheetProps, SIDE_POSITION } from './types';
import { AdaptiveSheetMethods } from '../../types.d';
import Animated, {
  runOnJS,
  runOnUI,
  useAnimatedReaction,
  useAnimatedStyle,
  useSharedValue,
  useWorkletCallback,
  useDerivedValue,
  withTiming,
  withSpring,
  cancelAnimation,
} from 'react-native-reanimated';
import {
  DEFAULT_ANIMATE_ON_MOUNT,
  DEFAULT_ENABLE_CONTENT_PANNING_GESTURE,
  DEFAULT_ENABLE_HANDLE_PANNING_GESTURE,
  DEFAULT_ENABLE_PAN_TO_CLOSE,
  DEFAULT_ENABLE_DRAG_TO_CLOSE,
  DEFAULT_SIDE_POSITION,
  DEFAULT_SHOW_HEADER,
  DEFAULT_HEADER_HEIGHT,
  DEFAULT_HEADER_CLOSE_BUTTON_COLOR,
  DEFAULT_TOP_INSET,
  DEFAULT_BOTTOM_INSET,
  DEFAULT_SNAP_POINT,
  MAX_SNAP_POINT_PERCENTAGE,
  MIN_SNAP_POINT_PERCENTAGE,
  DRAG_TO_CLOSE_THRESHOLD_PERCENTAGE,
  GESTURE_VELOCITY_THRESHOLD,
  GESTURE_MIN_DRAG_DISTANCE,
} from './constants';
import { styles } from './styles';
import { WINDOW_WIDTH, WINDOW_HEIGHT } from '../../constants';
import invariant from 'invariant';
import { View, Dimensions, StyleProp, ViewStyle } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import AdaptiveSideSheetHeader from './AdaptiveSideSheetHeader';

// 组件定义
type AdaptiveSideSheet = AdaptiveSheetMethods;

/**
 * 优化的边界限制函数 - 带过度拖拽阻尼效果
 * 性能优化：减少分支判断，使用数学运算替代 if-else
 */
const clampWithOverdrag = (value: number, min: number, max: number, maxOverdrag = 15, dampingFactor = 0.25): number => {
  'worklet';

  // 超出最大值
  if (value > max) {
    const overdrag = Math.min(value - max, maxOverdrag);
    return max + overdrag * dampingFactor;
  }

  // 超出最小值
  if (value < min) {
    const overdrag = Math.min(min - value, maxOverdrag);
    return min - overdrag * dampingFactor;
  }

  return value;
};

const AdaptiveSideSheetComponent = forwardRef<AdaptiveSideSheet, AdaptiveSideSheetProps>(function AdaptiveSideSheet(
  {
    // configuration
    index = 0,
    snapPoints = DEFAULT_SNAP_POINT,
    position = DEFAULT_SIDE_POSITION,
    animateOnMount = DEFAULT_ANIMATE_ON_MOUNT,

    // gesture configuration
    enableContentPanningGesture = DEFAULT_ENABLE_CONTENT_PANNING_GESTURE,
    enableHandlePanningGesture = DEFAULT_ENABLE_HANDLE_PANNING_GESTURE,
    enablePanToClose = DEFAULT_ENABLE_PAN_TO_CLOSE,
    enableDragToClose = DEFAULT_ENABLE_DRAG_TO_CLOSE,

    // layout
    handleWidth = 4,
    topInset = DEFAULT_TOP_INSET,
    bottomInset = DEFAULT_BOTTOM_INSET,
    containerWidth, // 移除默认值，让组件自动响应屏幕变化

    // styles
    containerStyle,
    style,
    backgroundStyle,
    handleStyle,

    // gesture handler
    activeOffsetX = [-5, 5], // 降低阈值，提高灵敏度

    // header
    showHeader = DEFAULT_SHOW_HEADER,
    headerComponent: CustomHeaderComponent,
    headerHeight = DEFAULT_HEADER_HEIGHT,
    headerTitle,
    headerLeftButton,
    headerRightButton,
    onHeaderLeftPress,
    onHeaderRightPress,
    headerTitleStyle,
    headerContainerStyle,
    headerCloseButtonColor = DEFAULT_HEADER_CLOSE_BUTTON_COLOR,

    // components
    backdropComponent,

    // callbacks
    onStateChange,
    onSizeChange,

    // children
    children,
  },
  ref,
): JSX.Element {
  const [currentContainerWidth, setCurrentContainerWidth] = useState(containerWidth || WINDOW_WIDTH);
  const [isScreenChanging, setIsScreenChanging] = useState(false); // 标记屏幕正在变化

  const isNewMode = useMemo((): boolean => {
    return !Array.isArray(snapPoints);
  }, [snapPoints]);

  const snapPointData = useMemo((): {
    minWidth: number;
    maxWidth: number;
    defaultWidth: number;
    isNewMode: boolean;
    normalizedPoints?: number[];
  } => {
    if (isNewMode) {
      const snapPointValue = snapPoints as string | number;

      // 规范默认快照点
      let defaultWidth: number;
      if (typeof snapPointValue === 'string' && snapPointValue.includes('%')) {
        const percentage = parseFloat(snapPointValue.replace('%', '')) / 100;
        defaultWidth = Number(currentContainerWidth) * percentage;
      } else {
        defaultWidth = Number(snapPointValue);
      }

      // 基于固定百分比计算最小和最大值
      const maxWidth = currentContainerWidth * MAX_SNAP_POINT_PERCENTAGE; // 85%
      const minWidth = currentContainerWidth * MIN_SNAP_POINT_PERCENTAGE; // 40%

      // 将默认宽度限制在最小和最大范围内
      const clampedDefault = Math.max(minWidth, Math.min(maxWidth, defaultWidth));

      return {
        defaultWidth: clampedDefault,
        minWidth,
        maxWidth,
        isNewMode: true,
      };
    } else {
      const points = Array.isArray(snapPoints) ? snapPoints : [];
      const normalized = points.map((point: string | number): number => {
        if (typeof point === 'string' && point.includes('%')) {
          const percentage = parseFloat(point.replace('%', '')) / 100;
          return Number(currentContainerWidth) * percentage;
        }
        return Number(point);
      });

      const maxWidth = Math.max(...normalized);

      return {
        defaultWidth: normalized[0] || 0,
        minWidth: Math.min(...normalized),
        maxWidth,
        normalizedPoints: normalized,
        isNewMode: false,
      };
    }
  }, [snapPoints, currentContainerWidth, isNewMode]);

  const maxSnapPoint = useMemo((): number => {
    return snapPointData.maxWidth;
  }, [snapPointData]);

  const closedPosition = useMemo((): number => {
    return position === SIDE_POSITION.LEFT ? -maxSnapPoint : maxSnapPoint;
  }, [maxSnapPoint, position]);

  const normalizedSnapPoints = useMemo((): number[] => {
    if (snapPointData.isNewMode) {
      return [snapPointData.defaultWidth];
    }
    return snapPointData.normalizedPoints || [];
  }, [snapPointData]);

  const [isVisible, setIsVisible] = useState(index !== -1);

  // 计算初始位置：如果 index !== -1，应该直接设置为目标位置，避免闪烁
  const getInitialPosition = (): number => {
    if (index === -1) {
      return closedPosition;
    }

    // 如果是打开状态，计算目标位置
    const targetWidth = normalizedSnapPoints[index] || normalizedSnapPoints[0] || 0;
    if (position === SIDE_POSITION.LEFT) {
      return -maxSnapPoint + targetWidth;
    } else {
      return maxSnapPoint - targetWidth;
    }
  };

  const animatedIndex = useSharedValue(index);
  const animatedPosition = useSharedValue(getInitialPosition());
  const animatedContainerWidth = useSharedValue(currentContainerWidth);
  const animatedMaxSnapPoint = useSharedValue(maxSnapPoint);
  const animatedClosedPosition = useSharedValue(closedPosition);
  const isScreenResizing = useSharedValue(false); // 标记屏幕正在调整大小
  const isAnimating = useSharedValue(false); // 标记是否正在动画
  const animatedCurrentIndex = useSharedValue(index); // 跟踪当前 index，用于检测变化
  const sheetOpacity = useSharedValue(index !== -1 ? 1 : 0); // 弹窗透明度，用于控制初始可见性

  // 添加状态来控制 Backdrop 的显示 - 延迟一帧以避免首帧灰色闪烁
  const [showBackdrop, setShowBackdrop] = useState(index !== -1);

  const animateToPosition = useWorkletCallback(
    (targetPosition: number, useSpringAnimation = true): void => {
      'worklet';

      // 取消当前动画，避免冲突
      cancelAnimation(animatedPosition);

      // 标记动画开始
      isAnimating.value = true;

      // 检查是否是关闭动画
      const isClosing = targetPosition === animatedClosedPosition.value;

      if (useSpringAnimation) {
        // 优化的 spring 动画配置，减少卡顿
        animatedPosition.value = withSpring(
          targetPosition,
          {
            damping: 35, // 增加阻尼，减少震荡
            stiffness: 350, // 提高刚度，加快响应
            mass: 0.6, // 降低质量，提升流畅度
            overshootClamping: false,
            restDisplacementThreshold: 0.01,
            restSpeedThreshold: 0.01,
          },
          (finished): void => {
            'worklet';
            // 动画完成时标记
            if (finished) {
              isAnimating.value = false;
              // 如果是关闭动画，隐藏弹窗
              if (isClosing) {
                sheetOpacity.value = 0;
              }
            }
          },
        );
      } else {
        // 使用 timing 动画
        animatedPosition.value = withTiming(
          targetPosition,
          {
            duration: 250,
          },
          (finished): void => {
            'worklet';
            // 动画完成时标记
            if (finished) {
              isAnimating.value = false;
              // 如果是关闭动画，隐藏弹窗
              if (isClosing) {
                sheetOpacity.value = 0;
              }
            }
          },
        );
      }
    },
    [animatedPosition, isAnimating, animatedClosedPosition, sheetOpacity],
  );

  const snapToIndex = useCallback(
    (nextIndex: number): void => {
      invariant(
        nextIndex >= -1 && nextIndex <= normalizedSnapPoints.length - 1,
        `'index' was provided but out of the provided snap points range! expected value to be between -1, ${normalizedSnapPoints.length - 1}`,
      );

      let nextPosition: number;
      if (nextIndex === -1) {
        // 关闭状态
        nextPosition = closedPosition;
      } else {
        // 根据方向和snapPoints计算位置
        const targetWidth = normalizedSnapPoints[nextIndex];
        if (position === SIDE_POSITION.LEFT) {
          nextPosition = -maxSnapPoint + targetWidth;
        } else {
          nextPosition = maxSnapPoint - targetWidth;
        }
      }

      requestAnimationFrame((): void => {
        runOnUI((): void => {
          'worklet';
          // 在动画开始前，确保弹窗可见
          if (nextIndex !== -1) {
            sheetOpacity.value = 1;
          }
          animatedIndex.value = nextIndex;
        })();
        runOnUI(animateToPosition)(nextPosition);
      });
    },
    [normalizedSnapPoints, closedPosition, animatedIndex, animateToPosition, position, maxSnapPoint, animatedPosition, sheetOpacity],
  );

  const snapToPosition = useCallback(
    (targetPosition: string | number): void => {
      const numPosition =
        typeof targetPosition === 'string' ? (parseFloat(targetPosition.replace('%', '')) * Number(currentContainerWidth)) / 100 : targetPosition;

      requestAnimationFrame((): void => {
        runOnUI(animateToPosition)(numPosition);
        runOnUI((): void => {
          'worklet';
          let nextIndex = normalizedSnapPoints.findIndex((snapPoint: number): boolean => snapPoint === numPosition);

          if (nextIndex === -1) {
            nextIndex = animatedIndex.value;
          }
          animatedIndex.value = nextIndex;
        })();
      });
    },
    [normalizedSnapPoints, animatedIndex, animateToPosition, currentContainerWidth],
  );

  const expand = useCallback((): void => {
    snapToIndex(normalizedSnapPoints.length - 1);
  }, [snapToIndex, normalizedSnapPoints]);

  const collapse = useCallback((): void => {
    snapToIndex(0);
  }, [snapToIndex]);

  const close = useCallback((): void => {
    snapToIndex(-1);
  }, [snapToIndex]);

  const forceClose = useCallback((): void => {
    requestAnimationFrame((): void => {
      runOnUI(animateToPosition)(closedPosition);
      runOnUI((): void => {
        'worklet';
        animatedIndex.value = -1;
      })();
    });
  }, [closedPosition, animatedIndex, animateToPosition]);

  useImperativeHandle(
    ref,
    (): AdaptiveSideSheet => ({
      snapToIndex,
      snapToPosition,
      expand,
      collapse,
      close,
      forceClose,
    }),
  );
  // 缓存所有动画样式的计算值，减少重复计算
  const animatedStyleValues = useDerivedValue(() => {
    'worklet';
    const pos = animatedPosition.value;
    const maxSnap = animatedMaxSnapPoint.value;
    const closed = animatedClosedPosition.value;
    const isVisible = pos !== closed;

    // 计算背景蒙层透明度（简化 interpolate 为线性计算）
    let backdropOpacity = 0;
    if (isVisible) {
      const currentWidth = Math.abs(pos - closed);
      backdropOpacity = Math.min(0.64, (currentWidth / maxSnap) * 0.64);
    }
      return {
      // 容器样式
      containerWidth: maxSnap,
      containerZIndex: isVisible ? 1000 : -1,

      // 弹窗样式
      sheetTranslateX: pos,
      sheetWidth: maxSnap,

      // 背景蒙层样式
      backdropOpacity,
      backdropPointerEvents: backdropOpacity > 0.01 ? ('auto' as const) : ('none' as const),

      // 手柄样式
      handleOpacity: isVisible ? 1 : 0,
    };
  }, [position]);

  const containerAnimatedStyle = useAnimatedStyle(() => ({
    width: animatedStyleValues.value.containerWidth,
    zIndex: animatedStyleValues.value.containerZIndex,
  }));

  const sheetAnimatedStyle = useAnimatedStyle(() => ({
    transform: [{ translateX: animatedStyleValues.value.sheetTranslateX }],
    width: animatedStyleValues.value.sheetWidth,
  }));

  // 背景蒙层动画样式
  const backdropAnimatedStyle = useAnimatedStyle(() => ({
    opacity: animatedStyleValues.value.backdropOpacity,
    pointerEvents: animatedStyleValues.value.backdropPointerEvents,
  }));

  // Header 可见宽度 - 使用 useDerivedValue 优化性能
  const headerVisibleWidth = useDerivedValue(() => {
    'worklet';
    const pos = animatedPosition.value;
    const maxSnap = animatedMaxSnapPoint.value;
    const currentIndex = animatedIndex.value;
        // 如果弹窗正在关闭，返回 0
    if (currentIndex === -1) {
      return 0;
    }

    let visibleWidth = 0;
    if (position === SIDE_POSITION.LEFT) {
      visibleWidth = Math.max(0, maxSnap + pos);
    } else {
      visibleWidth = Math.max(0, maxSnap - pos);
    }

    // 四舍五入到整数，避免亚像素渲染
    return Math.round(visibleWidth);
  }, [position]);

    // Header 动画样式
  const headerAnimatedStyle = useAnimatedStyle(() => {
    const width = headerVisibleWidth.value;
    const currentIndex = animatedIndex.value;

    return {
      width,
      opacity: currentIndex === -1 ? 0 : 1,
    };
  }, [position]);

  // 使用新版 Gesture API 优化性能
  const gestureStartPosition = useSharedValue(0);
  const shouldHandleGesture = useSharedValue(true);

  // 预计算边界值 - 性能优化：避免每帧重复计算
  const gestureBoundaries = useMemo(() => {
    // 左侧弹窗：从 closedPosition (负值) 到 0
    // 右侧弹窗：从 0 到 closedPosition (正值)
    return position === SIDE_POSITION.LEFT ? { min: closedPosition, max: 0 } : { min: 0, max: closedPosition };
  }, [position, closedPosition]);

  // 使用新版 Gesture.Pan() API - 性能优化：在 UI 线程处理手势
  const panGesture = useMemo(() => {
    return Gesture.Pan()
      .enabled(enableContentPanningGesture || enableHandlePanningGesture)
      .activeOffsetX(activeOffsetX)
      .onBegin(event => {
        'worklet';
        // 取消当前动画
        cancelAnimation(animatedPosition);

        // 记录手势开始时的位置
        gestureStartPosition.value = animatedPosition.value;

        // 检查触摸位置是否在允许的区域
        const currentWidth = Math.abs(animatedPosition.value - animatedClosedPosition.value);

        // 如果只启用手柄拖动，检查触摸位置是否在手柄区域
        if (!enableContentPanningGesture && enableHandlePanningGesture) {
          const handleZoneWidth = 40;
          let isInHandleZone = false;

          if (position === SIDE_POSITION.LEFT) {
            isInHandleZone = event.absoluteX >= currentWidth - handleZoneWidth && event.absoluteX <= currentWidth;
          } else {
            const sheetLeft = animatedContainerWidth.value - currentWidth;
            isInHandleZone = event.absoluteX >= sheetLeft && event.absoluteX <= sheetLeft + handleZoneWidth;
          }

          shouldHandleGesture.value = isInHandleZone;
        } else if (enableContentPanningGesture && enableHandlePanningGesture) {
          shouldHandleGesture.value = true;
        } else {
          shouldHandleGesture.value = false;
        }
      })
      .onUpdate(event => {
        'worklet';
        if (!shouldHandleGesture.value) {
          return;
        }

        // 计算新位置
        const newPosition = gestureStartPosition.value + event.translationX;

        // 使用优化的边界限制函数 - 减少分支判断
        animatedPosition.value = clampWithOverdrag(newPosition, gestureBoundaries.min, gestureBoundaries.max);
      })
      .onEnd(event => {
        'worklet';
        if (!shouldHandleGesture.value) {
          return;
        }

        const dragDistance = event.translationX;
        const velocityX = event.velocityX;
        const currentWidth = Math.abs(animatedPosition.value - animatedClosedPosition.value);
        let shouldClose = false;

        if (enablePanToClose) {
          if (position === SIDE_POSITION.LEFT) {
            const hasVelocity = velocityX < -GESTURE_VELOCITY_THRESHOLD && dragDistance < -GESTURE_MIN_DRAG_DISTANCE;
            shouldClose = hasVelocity;
          } else {
            const hasVelocity = velocityX > GESTURE_VELOCITY_THRESHOLD && dragDistance > GESTURE_MIN_DRAG_DISTANCE;
            shouldClose = hasVelocity;
          }
        }

        if (!shouldClose && enableDragToClose) {
          const dragToCloseThreshold = currentWidth * DRAG_TO_CLOSE_THRESHOLD_PERCENTAGE;

          if (position === SIDE_POSITION.LEFT) {
            const draggedWidth = Math.abs(dragDistance);
            shouldClose = dragDistance < 0 && draggedWidth > currentWidth - dragToCloseThreshold;
          } else {
            const draggedWidth = Math.abs(dragDistance);
            shouldClose = dragDistance > 0 && draggedWidth > currentWidth - dragToCloseThreshold;
          }
        }

        if (shouldClose) {
          runOnJS(snapToIndex)(-1);
        } else if (snapPointData.isNewMode) {
          const currentPos = animatedPosition.value;
          const { minWidth, maxWidth } = snapPointData;
          const maxSnap = animatedMaxSnapPoint.value;

          let finalPosition: number;

          if (position === SIDE_POSITION.LEFT) {
            const minPos = -maxSnap + minWidth; 
            const maxPos = -maxSnap + maxWidth; 

            if (currentPos > maxPos) {
              finalPosition = maxPos;
            } else if (currentPos < minPos) {
              finalPosition = minPos;
            } else {
              finalPosition = currentPos;
            }
          } else {
            const minPos = maxSnap - maxWidth; 
            const maxPos = maxSnap - minWidth; 

            if (currentPos < minPos) {
              finalPosition = minPos;
            } else if (currentPos > maxPos) {
              finalPosition = maxPos;
            } else {
              finalPosition = currentPos;
            }
          }

          animatedPosition.value = withSpring(
            finalPosition,
            {
              damping: 500,
              stiffness: 1000,
              mass: 3,
              overshootClamping: true,
              restDisplacementThreshold: 0.01,
              restSpeedThreshold: 0.01,
            },
            finished => {
              'worklet';
              if (finished && onSizeChange) {
                const maxSnap = animatedMaxSnapPoint.value;
                const containerHeight = WINDOW_HEIGHT;

                let visibleWidth = 0;
                if (position === SIDE_POSITION.LEFT) {
                  visibleWidth = Math.max(0, maxSnap + finalPosition);
                } else {
                  visibleWidth = Math.max(0, maxSnap - finalPosition);
                }

                runOnJS(onSizeChange)({
                  position: finalPosition,
                  visibleWidth,
                  visibleHeight: containerHeight,
                });
              }
            },
          );
        } else {
          let minDistance = Infinity;
          let targetIndex = 0;
          const maxSnap = animatedMaxSnapPoint.value;

          for (let idx = 0; idx < normalizedSnapPoints.length; idx++) {
            const width = normalizedSnapPoints[idx];
            let targetPos: number;
            if (position === SIDE_POSITION.LEFT) {
              targetPos = -maxSnap + width;
            } else {
              targetPos = maxSnap - width;
            }
            const distance = Math.abs(animatedPosition.value - targetPos);
            if (distance < minDistance) {
              minDistance = distance;
              targetIndex = idx;
            }
          }

          runOnJS(snapToIndex)(targetIndex);
        }
      });
  }, [
    enableContentPanningGesture,
    enableHandlePanningGesture,
    activeOffsetX,
    position,
    enablePanToClose,
    enableDragToClose,
    snapToIndex,
    snapPointData,
    normalizedSnapPoints,
    animatedPosition,
    animatedClosedPosition,
    animatedMaxSnapPoint,
    animatedContainerWidth,
    gestureStartPosition,
    shouldHandleGesture,
    gestureBoundaries,
    onSizeChange,
  ]);

  // 监听 containerWidth prop 变化
  useEffect((): void => {
    const newWidth = containerWidth || WINDOW_WIDTH;
    if (newWidth !== currentContainerWidth) {
      setCurrentContainerWidth(newWidth);
      animatedContainerWidth.value = newWidth;
    }
  }, [containerWidth, currentContainerWidth, animatedContainerWidth]);

  // 性能优化：使用防抖处理屏幕尺寸变化
  const handleScreenResize = useCallback(
    (newWidth: number) => {
      // 批量更新状态
      setIsScreenChanging(true);
      setCurrentContainerWidth(newWidth);

      const currentIndex = animatedIndex.value;

      // 重新计算 normalizedSnapPoints
      const newNormalizedSnapPoints = (Array.isArray(snapPoints) ? snapPoints : []).map((point: string | number): number => {
        if (typeof point === 'string' && point.includes('%')) {
          const percentage = parseFloat(point.replace('%', '')) / 100;
          return Number(newWidth) * percentage;
        }
        return Number(point);
      });

      const newMaxSnapPoint = Math.max(...newNormalizedSnapPoints);
      const newClosedPosition = position === SIDE_POSITION.LEFT ? -newMaxSnapPoint : newMaxSnapPoint;

      // 在 UI 线程批量更新所有 SharedValue
      runOnUI(() => {
        'worklet';
        isScreenResizing.value = true;

        // 取消所有动画
        cancelAnimation(animatedPosition);
        cancelAnimation(animatedMaxSnapPoint);
        cancelAnimation(animatedClosedPosition);

        // 批量更新值
        // 更新位置
        if (currentIndex === -1) {
          // 关闭状态
          animatedPosition.value = newClosedPosition;
        } else if (currentIndex >= 0 && currentIndex < newNormalizedSnapPoints.length) {
          // 打开状态 - 重新计算位置
          const targetWidth = newNormalizedSnapPoints[currentIndex];
          animatedPosition.value = position === SIDE_POSITION.LEFT ? -newMaxSnapPoint + targetWidth : newMaxSnapPoint - targetWidth;
        }

        isScreenResizing.value = false;
      })();

      // 延迟重置标记
      setTimeout(() => {
        setIsScreenChanging(false);
      }, 100);
    },
    [currentContainerWidth, snapPoints, position, animatedIndex],
  );

  // 监听屏幕尺寸变化
  useEffect((): (() => void) | void => {
    if (containerWidth !== undefined) {
      return;
    }
    
    let previousWidth = currentContainerWidth;
    let debounceTimer: NodeJS.Timeout | null = null;

    const subscription = Dimensions.addEventListener('change', ({ window }) => {
      const newWidth = window.width;

      if (newWidth !== previousWidth) {
        previousWidth = newWidth;

        // 使用防抖减少处理频率
        if (debounceTimer) {
          clearTimeout(debounceTimer);
        }

        debounceTimer = setTimeout(() => {
          handleScreenResize(newWidth);
          debounceTimer = null;
        }, 100);
      }
    });

    return () => {
      if (debounceTimer) {
        clearTimeout(debounceTimer);
      }
      subscription?.remove();
    };
  }, [containerWidth, currentContainerWidth, handleScreenResize]);

  // 同步更新 SharedValue
  useEffect((): void => {
    animatedMaxSnapPoint.value = maxSnapPoint;
    animatedClosedPosition.value = closedPosition;
  }, [maxSnapPoint, closedPosition, animatedMaxSnapPoint, animatedClosedPosition]);

  // 监听 normalizedSnapPoints 和 closedPosition 变化，同步更新弹窗位置
  useEffect((): void => {
    // 如果屏幕正在变化，跳过此更新（由屏幕变化的 useEffect 处理）
    if (isScreenChanging) {
      return;
    }

    const currentIndex = animatedIndex.value;

    // 如果弹窗是关闭状态，直接更新到新的关闭位置（无动画）
    if (currentIndex === -1) {
      runOnUI((): void => {
        'worklet';
        animatedPosition.value = closedPosition;
      })();
    } else if (currentIndex >= 0 && currentIndex < normalizedSnapPoints.length) {
      // 如果弹窗是打开状态，重新计算并动画到新位置
      requestAnimationFrame((): void => {
        snapToIndex(currentIndex);
      });
    }
  }, [normalizedSnapPoints, closedPosition, animatedIndex, snapToIndex, animatedPosition, isScreenChanging]);

  // 性能优化：合并两个 useAnimatedReaction，减少重复监听
  // 监听索引变化，同时处理可见性更新和回调触发
  useAnimatedReaction(
    (): { index: number; isAnimating: boolean } => ({
      index: animatedIndex.value,
      isAnimating: isAnimating.value,
    }),
    ({ index, isAnimating }, previous): void => {
      // 1. 更新可见性状态（索引变化时）
      if (previous && index !== previous.index) {
        runOnJS(setIsVisible)(index !== -1);
      }

      // 2. 触发 onChange 回调（只在动画停止且索引是整数时）
      if (!isScreenResizing.value && !isAnimating && index % 1 === 0 && index !== animatedCurrentIndex.value) {
        animatedCurrentIndex.value = index;
        if (onStateChange) {
          runOnJS(onStateChange)(index);
        }
      }
    },
    [onStateChange],
  );

  // 监听位置变化，触发 onSizeChange 回调（带时间节流优化）
  // 使用 shared value 存储上次触发时间
  const lastCallbackTime = useSharedValue(0);
  // 使用 shared value 存储忽略回调的截止时间
  const ignoreCallbackUntil = useSharedValue(0);

  // 监听 index 变化，在状态变化时设置忽略期
  useAnimatedReaction(
    (): { index: number; isAnimating: boolean } => ({
      index: animatedIndex.value,
      isAnimating: isAnimating.value,
    }),
    ({ index, isAnimating }, previous): void => {
      'worklet';
      console.log('[AdaptiveSideSheet] Index/Animation changed:', 'index:', index, 'isAnimating:', isAnimating, 'previous:', previous);
      // 当动画停止且索引变为 0（打开）时，忽略接下来 500ms 的回调
      if (previous && !isAnimating && index === 0 && previous.index !== 0) {
        ignoreCallbackUntil.value = Date.now() + 500;
        console.log('[AdaptiveSideSheet] Ignoring callbacks for 500ms');
      }
    },
    [],
  );

  useAnimatedReaction(
    () => animatedPosition.value,
    _position => {
      'worklet';
      if (!onSizeChange) {
        return;
      }

      const now = Date.now();

      // 检查是否在忽略期内
      if (now < ignoreCallbackUntil.value) {
        console.log('[AdaptiveSideSheet] In ignore period, remaining:', ignoreCallbackUntil.value - now, 'ms');
        return;
      }

      const timeSinceLastCallback = now - lastCallbackTime.value;

      // 时间节流：只有距离上次回调至少 200ms 才触发
      if (lastCallbackTime.value > 0 && timeSinceLastCallback < 200) {
        return;
      }

      const maxSnap = animatedMaxSnapPoint.value;
      const containerHeight = WINDOW_HEIGHT;

      let visibleWidth = 0;
      if (position === SIDE_POSITION.LEFT) {
        visibleWidth = Math.max(0, maxSnap + _position);
      } else {
        visibleWidth = Math.max(0, maxSnap - _position);
      }

      // 更新上次触发时间
      lastCallbackTime.value = now;

      runOnJS(onSizeChange)({
        position: _position,
        visibleWidth,
        visibleHeight: containerHeight,
      });
    },
    [onSizeChange, position],
  );

  

  useEffect((): void => {
    // 只在需要动画时才执行 snapToIndex
    // 如果 animateOnMount = false，初始位置已经在 getInitialPosition() 中设置正确
    if (animateOnMount && index !== -1) {
      requestAnimationFrame((): void => {
        snapToIndex(index);
      });
    } else if (!animateOnMount && index !== -1) {
      // 如果不需要动画，但是打开状态，确保 animatedIndex 同步
      runOnUI((): void => {
        'worklet';
        animatedIndex.value = index;
      })();
    }
  }, [animateOnMount, index, snapToIndex, animatedIndex]);

  // 当 index 变化时控制 Backdrop 的显示
  useEffect(() => {
    if (index !== -1) {
      // 打开弹窗时，延迟一帧显示 Backdrop，确保 sheet 先渲染
      setShowBackdrop(false);
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          setShowBackdrop(true);
        });
      });
    } else {
      // 关闭弹窗时，立即隐藏 Backdrop
      setShowBackdrop(false);
    }
  }, [index]);

  const containerStyleMemo = useMemo(
    (): StyleProp<ViewStyle> => [
      styles.container,
      position === SIDE_POSITION.LEFT ? styles.containerLeft : styles.containerRight,
      {
        paddingTop: topInset,
        paddingBottom: bottomInset,
      },
      containerAnimatedStyle,
      containerStyle,
    ],
    [containerAnimatedStyle, containerStyle, position, topInset, bottomInset],
  );

  const sheetStyleMemo = useMemo((): StyleProp<ViewStyle> => {
    return [styles.sheet, position === SIDE_POSITION.LEFT ? styles.sheetLeft : styles.sheetRight, sheetAnimatedStyle, backgroundStyle, style];
  }, [sheetAnimatedStyle, backgroundStyle, style, position]);

  // 手柄动画样式 - 使用缓存的值
  const handleAnimatedStyle = useAnimatedStyle(() => ({
    opacity: animatedStyleValues.value.handleOpacity,
  }));

  const handleStyleMemo = useMemo(
    (): StyleProp<ViewStyle> => [
      styles.handle,
      position === SIDE_POSITION.LEFT ? styles.handleLeft : styles.handleRight,
      { width: handleWidth },
      handleAnimatedStyle,
      handleStyle,
    ],
    [handleStyle, position, handleWidth, handleAnimatedStyle],
  );

  const handleBackdropPress = useCallback((): void => {
    close();
  }, [close]);

  const handleHeaderRightPressInternal = useCallback((): void => {
    if (onHeaderRightPress) {
      onHeaderRightPress();
    } else {
      close();
    }
  }, [onHeaderRightPress, close]);

  const BackdropComponent = backdropComponent;

  // 根据当前状态决定是否允许点击事件穿透
  // 当弹窗关闭时（isVisible = false），设置 pointerEvents 为 'none' 以允许点击事件穿透
  const containerPointerEvents = isVisible ? 'box-none' : 'none';

  // 内容容器样式 - 当没有 Header 时，需要添加 topInset
  const contentContainerStyleMemo = useMemo(
    (): StyleProp<ViewStyle> => [styles.contentContainer, !showHeader && topInset > 0 ? { paddingTop: topInset } : null],
    [showHeader, topInset],
  );

  return (
    <>
      {/* Backdrop - 自定义背景蒙层 - 延迟显示以避免首帧灰色闪烁 */}
      {BackdropComponent && showBackdrop && (
        <BackdropComponent
          animatedIndex={animatedIndex}
          animatedPosition={animatedPosition}
          style={[styles.backdrop, backdropAnimatedStyle]}
          onPress={handleBackdropPress}
        />
      )}

      {/* Side Sheet Container - 使用新版 GestureDetector */}
      <Animated.View style={containerStyleMemo} pointerEvents={containerPointerEvents}>
        <GestureDetector gesture={panGesture}>
          <Animated.View style={sheetStyleMemo}>
            {/* Handle */}
            {handleWidth > 0 && <Animated.View style={handleStyleMemo} />}

            {/* Header */}
            {showHeader && (
              <Animated.View style={headerAnimatedStyle}>
                {CustomHeaderComponent ? (
                  <CustomHeaderComponent
                    title={headerTitle}
                    height={headerHeight}
                    topInset={topInset}
                    leftButton={headerLeftButton}
                    rightButton={headerRightButton}
                    onLeftPress={onHeaderLeftPress}
                    onRightPress={handleHeaderRightPressInternal}
                    titleStyle={headerTitleStyle}
                    containerStyle={headerContainerStyle}
                    closeButtonColor={headerCloseButtonColor}
                    sheetType="side"
                  />
                ) : (
                  <AdaptiveSideSheetHeader
                    title={headerTitle}
                    height={headerHeight}
                    topInset={topInset}
                    leftButton={headerLeftButton}
                    rightButton={headerRightButton}
                    onLeftPress={onHeaderLeftPress}
                    onRightPress={handleHeaderRightPressInternal}
                    titleStyle={headerTitleStyle}
                    containerStyle={headerContainerStyle}
                    closeButtonColor={headerCloseButtonColor}
                  />
                )}
              </Animated.View>
            )}

            {/* Content Container */}
            <View style={contentContainerStyleMemo}>{children}</View>
          </Animated.View>
        </GestureDetector>
      </Animated.View>
    </>
  );
});

const AdaptiveSideSheet = memo(AdaptiveSideSheetComponent);
AdaptiveSideSheet.displayName = 'AdaptiveSideSheet';

export default AdaptiveSideSheet;
